clear
clc
close all

% 关于如何设置OFDM有效参数范围的参考https://www.mathworks.com/help/comm/ug/ofdm-transmitter-and-receiver.html

% rng(0)
% M = 4;                 % Modulator alphabet
% k = log2(M);           % Bits/symbol
% numSC = 128;           % Number of OFDM subcarriers
% cpLen = 32;            % OFDM cyclic prefix length
% maxBitErrors = 100;    % Maximum number of bit errors
% maxNumBits = 1e7;      % Maximum number of bits transmitted
% numDC = 117;
% NumSymbols = 10000;
% sps = 20e3;
% sr = numDC * sps;
%
% frameSize = [k*numDC NumSymbols];
% ofdmMod = comm.OFDMModulator( ...
%     FFTLength=numSC, ...
%     CyclicPrefixLength=cpLen, ...
%     Windowing=true, ...
%     WindowLength=16, ...
%     NumSymbols=NumSymbols);
% ofdmDemod = comm.OFDMDemodulator( ...
%     FFTLength=numSC, ...
%     CyclicPrefixLength=cpLen, NumSymbols=NumSymbols);
% errorRate = comm.ErrorRate(ResetInputPort=true);
% errorRate1 = comm.ErrorRate(ResetInputPort=true);
% errorRate2 = comm.ErrorRate(ResetInputPort=true);
%
% dataIn = randi([0,1],frameSize);              % Generate binary data
% qpskTx = pskmod(dataIn,M,InputType="bit");    % Apply QPSK modulation
% txSig = ofdmMod(qpskTx);
% bw = numDC*sps;
%
% [txSig3, b] = lowpass(txSig, bw/2, numSC*sps, ...
%                 ImpulseResponse = "fir", ...
%                 Steepness = 0.9, StopbandAttenuation=200);
%
% h1 = designMultirateFIR(5,1, 1000);
% txsig1 = resample(double(txSig),5,1,h1);
%
% h2 = designMultirateFIR(1,5, 1000);
% txsig2 = resample(double(txsig1),1,5,h2);
%
%
% sum(abs(txsig2-txSig));
%
%
% qpskRx = ofdmDemod(txSig);
% dataOut = pskdemod(qpskRx,M,OutputType="bit");
% errorStats = errorRate(dataIn(:),dataOut(:),0);
%
%
% qpskRx1 = ofdmDemod(txsig2);
% dataOut1 = pskdemod(qpskRx1,M,OutputType="bit");
% errorStats1 = errorRate1(dataIn(:),dataOut1(:),0);
%
% qpskRx2 = ofdmDemod(txSig3);
% dataOut2 = pskdemod(qpskRx2,M,OutputType="bit");
% errorStats2 = errorRate2(dataIn(:),dataOut2(:),0);
%
%
% sum(abs(dataOut1-dataOut));

%%
TimeDuration = 1;
SampleRate = 200e3;
ModulatorOrder = 4;
MasterClockRate = 20e6;
SamplePerSymbol = 1;
Subcarrierspacing = 10e3;

ModulatorConfig.base.mode = 'psk';
ModulatorConfig.base.PhaseOffset = pi/8;
ModulatorConfig.base.SymbolOrder = 'gray';
ModulatorConfig.ofdm.FFTLength = 128;
ModulatorConfig.ofdm.NumGuardBandCarriers = [6; 5];
ModulatorConfig.ofdm.InsertDCNull = false;
ModulatorConfig.ofdm.CyclicPrefixLength = 16;
ModulatorConfig.ofdm.Windowing = false;
ModulatorConfig.ofdm.WindowLength = 1;
ModulatorConfig.ofdm.OversamplingFactor = 1;
ModulatorConfig.ofdm.Subcarrierspacing = 10e3;

CarrierFrequency = 5e6;
IqImbalanceConfig.A = 3;
IqImbalanceConfig.P = 10;
PhaseNoiseConfig.Level = -50;
PhaseNoiseConfig.FrequencyOffset = 20;
MemoryLessNonlinearityConfig.Method = 'Saleh model';
MemoryLessNonlinearityConfig.InputScaling = 0;
MemoryLessNonlinearityConfig.AMAMParameters = [2.1587 1.1517];
MemoryLessNonlinearityConfig.AMPMParameters =  [4.0033 9.1040];
MemoryLessNonlinearityConfig.OutputScaling = 0;
MemoryLessNonlinearityConfig.ReferenceImpedance = 1;
ThermalNoiseConfig.NoiseTemperature = 290;
AGCConfig.AveragingLength = 256 * 4;
AGCConfig.MaxPowerGain = 400;

source = RandomSource(SampleRate=SampleRate, ...
    TimeDuration=TimeDuration, ...
    ModulatorOrder=ModulatorOrder, ...
    SamplePerSymbol=SamplePerSymbol);

x = source();

%% 单天线场景

txRF = TRFSimulator(StartTime=0.2, ...
    SampleRate = SampleRate, ...
    CarrierFrequency=CarrierFrequency, ...
    IqImbalanceConfig=IqImbalanceConfig, ...
    PhaseNoiseConfig=PhaseNoiseConfig, ...
    OutputPower=-20, ...
    MasterClockRate = MasterClockRate, ...
    MemoryLessNonlinearityConfig=MemoryLessNonlinearityConfig);
rayChannel = Rayleigh(CarrierFrequency=CarrierFrequency, ...
    SampleRate=SampleRate, PathDelays=0, ...
    AveragePathGains=0, MaximumDopplerShift=0);

ricChannel = Rician(CarrierFrequency=CarrierFrequency, ...
    SampleRate=SampleRate, PathDelays=0, ...
    AveragePathGains=0, MaximumDopplerShift=0);

rxRF = RRFSimulator(StartTime=0, TimeDuration=2, SampleRate=SampleRate, ...
    NumReceiveAntennas=1, CarrierFrequency=200e3, Bandwidth=20e3, ...
    MasterClockRate=MasterClockRate, ...
    MemoryLessNonlinearityConfig=MemoryLessNonlinearityConfig, ...
    ThermalNoiseConfig=ThermalNoiseConfig, ...
    PhaseNoiseConfig=PhaseNoiseConfig, ...
    AGCConfig=AGCConfig, ...
    IqImbalanceConfig=IqImbalanceConfig);

baseBandSignal = OFDM(SampleRate=SampleRate, ...
    TimeDuration=TimeDuration, ...
    ModulatorOrder=ModulatorOrder, ...
    ModulatorConfig=ModulatorConfig);

x1= baseBandSignal(x);
x1 = txRF(x1);
x1 = rayChannel(x1);
y1 = rxRF({x1});


%% 多天线场景
NumTransmitAntennas = 2;
NumReceiveAntennas = 1;

txRF = TRFSimulator(StartTime=0.2, ...
    SampleRate = SampleRate, ...
    CarrierFrequency=CarrierFrequency, ...
    IqImbalanceConfig=IqImbalanceConfig, ...
    PhaseNoiseConfig=PhaseNoiseConfig, ...
    MasterClockRate = MasterClockRate, ...
    MemoryLessNonlinearityConfig=MemoryLessNonlinearityConfig);
mimoChannel = MIMO(CarrierFrequency=CarrierFrequency, ...
    SampleRate=SampleRate, PathDelays=0, ...
    AveragePathGains=0, MaximumDopplerShift=0, ...
    NumTransmitAntennas=NumTransmitAntennas, ...
    NumReceiveAntennas=NumReceiveAntennas);
rxRF = RRFSimulator(StartTime=0, TimeDuration=2, SampleRate=SampleRate, ...
    NumReceiveAntennas=NumReceiveAntennas, CarrierFrequency=200e3, Bandwidth=20e3, ...
    MasterClockRate=MasterClockRate, ...
    MemoryLessNonlinearityConfig=MemoryLessNonlinearityConfig, ...
    ThermalNoiseConfig=ThermalNoiseConfig, ...
    PhaseNoiseConfig=PhaseNoiseConfig, ...
    AGCConfig=AGCConfig, ...
    IqImbalanceConfig=IqImbalanceConfig);

baseBandSignal = OFDM(SampleRate=SampleRate, ...
    TimeDuration=TimeDuration, ...
    ModulatorOrder=ModulatorOrder, ...
    NumTransmitAntennas=NumTransmitAntennas, ...
    ModulatorConfig=ModulatorConfig);

x2 = baseBandSignal(x);
x2 = txRF(x2);
x2 = mimoChannel(x2);
y2 = rxRF({x2});

NumTransmitAntennas = 2;
NumReceiveAntennas = 2;

txRF = TRFSimulator(StartTime=0.2, ...
    SampleRate = SampleRate, ...
    CarrierFrequency=CarrierFrequency, ...
    IqImbalanceConfig=IqImbalanceConfig, ...
    PhaseNoiseConfig=PhaseNoiseConfig, ...
    MasterClockRate = MasterClockRate, ...
    MemoryLessNonlinearityConfig=MemoryLessNonlinearityConfig);
mimoChannel = MIMO(CarrierFrequency=CarrierFrequency, ...
    SampleRate=SampleRate, PathDelays=0, ...
    AveragePathGains=0, MaximumDopplerShift=0, ...
    NumTransmitAntennas=NumTransmitAntennas, ...
    NumReceiveAntennas=NumReceiveAntennas);
rxRF = RRFSimulator(StartTime=0, TimeDuration=2, SampleRate=SampleRate, ...
    NumReceiveAntennas=NumReceiveAntennas, CarrierFrequency=200e3, Bandwidth=20e3, ...
    MasterClockRate=MasterClockRate, ...
    MemoryLessNonlinearityConfig=MemoryLessNonlinearityConfig, ...
    ThermalNoiseConfig=ThermalNoiseConfig, ...
    PhaseNoiseConfig=PhaseNoiseConfig, ...
    AGCConfig=AGCConfig, ...
    IqImbalanceConfig=IqImbalanceConfig);

baseBandSignal = OFDM(SampleRate=SampleRate, ...
    TimeDuration=TimeDuration, ...
    ModulatorOrder=ModulatorOrder, ...
    NumTransmitAntennas=NumTransmitAntennas, ...
    ModulatorConfig=ModulatorConfig);

x3 = baseBandSignal(x);
x3 = txRF(x3);
x3 = mimoChannel(x3);
y3 = rxRF({x3});

NumTransmitAntennas = 1;
NumReceiveAntennas = 2;

txRF = TRFSimulator(StartTime=0.2, ...
    SampleRate = SampleRate, ...
    CarrierFrequency=CarrierFrequency, ...
    IqImbalanceConfig=IqImbalanceConfig, ...
    PhaseNoiseConfig=PhaseNoiseConfig, ...
    MasterClockRate = MasterClockRate, ...
    MemoryLessNonlinearityConfig=MemoryLessNonlinearityConfig);
mimoChannel = MIMO(CarrierFrequency=CarrierFrequency, ...
    SampleRate=SampleRate, PathDelays=0, ...
    AveragePathGains=0, MaximumDopplerShift=0, ...
    NumTransmitAntennas=NumTransmitAntennas, ...
    NumReceiveAntennas=NumReceiveAntennas);
rxRF = RRFSimulator(StartTime=0, TimeDuration=2, SampleRate=SampleRate, ...
    NumReceiveAntennas=NumReceiveAntennas, CarrierFrequency=200e3, Bandwidth=20e3, ...
    MasterClockRate=MasterClockRate, ...
    MemoryLessNonlinearityConfig=MemoryLessNonlinearityConfig, ...
    ThermalNoiseConfig=ThermalNoiseConfig, ...
    PhaseNoiseConfig=PhaseNoiseConfig, ...
    AGCConfig=AGCConfig, ...
    IqImbalanceConfig=IqImbalanceConfig);

baseBandSignal = OFDM(SampleRate=SampleRate, ...
    TimeDuration=TimeDuration, ...
    ModulatorOrder=ModulatorOrder, ...
    NumTransmitAntennas=NumTransmitAntennas, ...
    ModulatorConfig=ModulatorConfig);

x4 = baseBandSignal(x);
x4 = txRF(x4);
x4 = mimoChannel(x4);
y4 = rxRF({x4});
